#include "LevelManager.h"
#include <cocostudio/cocostudio.h>

#include "../../Data/GameData.h"
#include "../../Framework/SceneManager.h"
#include "../../Objects/Ghost/Level/GhostLevel.h"
#include "../../Scenes/Menu/MenuManager.h"
#include "../../Player/PlayerInfo.h"
#include "../../Framework/SoundManager.h"
#define kLevelPerPage 20
#define kMaxRow 4
#define kMaxCol 5
#define kGhostHeight 550
#define kGhostWidth 400

using namespace cocostudio;

bool LevelManager::s_isActive = false;
EGameMode LevelManager::s_mode = EGameMode::kMode_Easy;
int LevelManager::s_ID = 1;

cocos2d::Scene* LevelManager::createScene()
{
	auto scene = Scene::create();
	auto layer = LevelManager::create();
	scene->addChild(layer);
	return scene;
}

bool LevelManager::init()
{
	if (!Layer::init())
	{
		return false;
	}

	setKeypadEnabled(true);
	m_screenSize = Director::getInstance()->getVisibleSize();
	initalize();

	return true;
}

LevelManager::~LevelManager()
{
	SpriteFrameCache::getInstance()->removeUnusedSpriteFrames();
	SpriteFrameCache::getInstance()->removeSpriteFrames();
	TextureCache::getInstance()->removeAllTextures();
}

void LevelManager::initalize()
{
	s_isActive = false;

	initBackground();
	initPanel();
	initButton();
    auto listener = EventListenerTouchOneByOne::create();
    listener->setSwallowTouches(true);
    listener->onTouchBegan = CC_CALLBACK_2(LevelManager::onTouchBegan, this);
    listener->onTouchMoved = CC_CALLBACK_2(LevelManager::onTouchMoved, this);
    listener->onTouchEnded = CC_CALLBACK_2(LevelManager::onTouchEnded, this);
    
    this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);
    m_isTouch = false;
    m_pTouchBegan = Vec2::ZERO;

}

void LevelManager::initBackground()
{
	Sprite* background = nullptr;

	switch (s_mode)
	{
	case EGameMode::kMode_Easy:
		background = Sprite::create("bg_easy.png");
		break;
	case EGameMode::kMode_Normal:
		background = Sprite::create("bg_normal.png");
		break;
	case EGameMode::kMode_Hard:
		background = Sprite::create("bg_hard.png");
		break;
	}

	float scaleX = m_screenSize.width / background->getContentSize().width;
	float scaleY = m_screenSize.height / background->getContentSize().height;

	background->setScale(scaleX, scaleY);
	background->setAnchorPoint(Vec2(0.5f, 0.5f));
	background->setPosition(Vec2(m_screenSize.width / 2, m_screenSize.height / 2));

	this->addChild(background);
}

void LevelManager::initPanel()
{
	m_currPage = 1;
	float rateLevelPerPage = 0;
	int maxLevel = 0;
    // maxLevel = 100;
	switch (s_mode)
	{
	case EGameMode::kMode_Easy:
		GameData::getInstance()->readEasy();
		maxLevel = GameData::getInstance()->config.NumOfEasyLevel;
           
		rateLevelPerPage = (float)maxLevel / (float)kLevelPerPage;
		break;
	case EGameMode::kMode_Normal:
		GameData::getInstance()->readNormal();
		maxLevel = GameData::getInstance()->config.NumOfNormalLevel;
		rateLevelPerPage = (float)maxLevel / (float)kLevelPerPage;
		break;
	case EGameMode::kMode_Hard:
		GameData::getInstance()->readHard();
		maxLevel = GameData::getInstance()->config.NumOfHardLevel;
		rateLevelPerPage = (float)maxLevel / (float)kLevelPerPage;
		break;
	}

	if (rateLevelPerPage == (int)rateLevelPerPage)
		m_numPage = (int)rateLevelPerPage;
	else
		m_numPage = (int)rateLevelPerPage + 1;

	float canvasRow = m_screenSize.height / (kMaxRow + 1);

	m_panel = Node::create();
	m_panel->setAnchorPoint(Vec2(0, 1.0f));
	m_panel->setPosition(0, canvasRow * 4);

	float expectGhostHeight = canvasRow*0.8f;
	float scale = expectGhostHeight / kGhostHeight;
    //scale*=2;
    GhostObject::ChangePositionChomponent(scale); // thay doi scale tuong ung voi scene level
    
	float ghostHeight = kGhostHeight * scale;
	float ghostWidth = kGhostWidth * scale;
	m_paddingHeight = canvasRow - ghostHeight;
	m_paddingWidth = m_screenSize.width / (kMaxCol + 1);
	float space = (m_screenSize.width - (ghostWidth * kMaxCol) - (m_paddingWidth * 2)) / (kMaxCol - 1);

	int currLevel = 1;
	bool limit = false;

	for (int iPage = 1; iPage <= m_numPage; iPage++)
	{
		Node* page = Node::create();
		page->setAnchorPoint(Vec2(0, 1.0f));
		page->setPosition(Vec2((iPage - 1) * m_screenSize.width, 0));

		for (int i = 0; i < kMaxRow; i++)
		{
			for (int j = 0; j < kMaxCol; j++)
			{
				GhostLevel* ghost = new GhostLevel();
				Vec2 position = Vec2(m_paddingWidth + ghostWidth / 2 + j * ghostWidth + (j * space),
					ghostHeight / 2 - i * ghostHeight - (i * m_paddingHeight));
                int star = PlayerInfo::getInstance()->level->getLevelStar(LevelManager::s_mode, currLevel);
                EGhostColor ghostColor;
				switch (s_mode)
				{
				case EGameMode::kMode_Easy:
                        switch (star) {
                            case -1:
                                ghostColor = EGhostColor::kGhostColor_Easy_NonStar;
                                break;
                            case 0:
                                ghostColor = EGhostColor::kGhostColor_Easy_0Star;
                                break;
                            case 1:
                                ghostColor = EGhostColor::kGhostColor_Easy_1Star;
                                break;
                            case 2:
                                ghostColor = EGhostColor::kGhostColor_Easy_2Star;
                                break;
                            case 3:
                                ghostColor = EGhostColor::kGhostColor_Easy_3Star;
                                break;
                            default:
                                break;
                        }
					break;
				case EGameMode::kMode_Normal:
                        switch (star) {
                            case -1:
                                ghostColor = EGhostColor::kGhostColor_Normal_NonStar;
                                break;
                            case 0:
                                ghostColor = EGhostColor::kGhostColor_Normal_0Star;
                                break;
                            case 1:
                                ghostColor = EGhostColor::kGhostColor_Normal_1Star;
                                break;
                            case 2:
                                ghostColor = EGhostColor::kGhostColor_Normal_2Star;
                                break;
                            case 3:
                                ghostColor = EGhostColor::kGhostColor_Normal_3Star;
                                break;
                            default:
                                break;
                        }

					break;
				case EGameMode::kMode_Hard:
                        switch (star) {
                            case -1:
                                ghostColor = EGhostColor::kGhostColor_Hard_NoneStar;
                                break;
                            case 0:
                                ghostColor = EGhostColor::kGhostColor_Hard_0Star;
                                break;
                            case 1:
                                ghostColor = EGhostColor::kGhostColor_Hard_1Star;
                                break;
                            case 2:
                                ghostColor = EGhostColor::kGhostColor_Hard_2Star;
                                break;
                            case 3:
                                ghostColor = EGhostColor::kGhostColor_Hard_3Star;
                                break;
                            default:
                                break;
                        }

					break;
				}
                 ghost->initalize(ghostColor, EGhostEyeColor::kGhostEyeColor_Orange, position, scale, currLevel);
				page->addChild(ghost);
				currLevel++;

				if (currLevel - 1 == maxLevel)
				{
					limit = true;
					break;
				}
			}
			if (limit)
				break;
		}
		m_panel->addChild(page);

		if (limit)
			break;
	}
	this->addChild(m_panel);
}

void LevelManager::initButton()
{
	Button* btnBack = Button::create("arrow_home.png");
   
	btnBack->setRotation(180);

	float rowHeight = m_screenSize.height / (kMaxRow + 1);
	float expectBackHeight = rowHeight*0.7;
	float backScale = expectBackHeight / btnBack->getContentSize().height;
	btnBack->setScale(backScale);
	btnBack->setPosition(Vec2(btnBack->getContentSize().width*backScale / 2 + 20, expectBackHeight / 2 + 20));
	btnBack->addClickEventListener(CC_CALLBACK_0(LevelManager::tapBack, this));

	this->addChild(btnBack);

    Button* temp = Button::create("page-marker.png");
    float expectButtonPageHeight = rowHeight*0.3f;
    float ButtonPageScale = expectButtonPageHeight / temp->getContentSize().height;
    float btnPageWidth = temp->getContentSize().width*ButtonPageScale;
    float btnPageHeight = temp->getContentSize().height*ButtonPageScale;
    
	float kButtonPadding = m_paddingWidth * 3 / 2;
	float space = (m_screenSize.width - (btnPageWidth * m_numPage) - (kButtonPadding * 2)) / (m_numPage - 1);

	for (int i = 0; i < m_numPage; i++)
	{
		Button* btnPage = Button::create("page-marker.png", "page-marker_over.png", "page-marker_over.png");
		btnPage->addClickEventListener(CC_CALLBACK_1(LevelManager::tapPage, this));
		btnPage->setTag(i + 1);
		if (i == 0)
		{
			btnPage->setEnabled(false);
			btnPage->loadTextureNormal("page-marker_over.png");
		}
		m_pages.pushBack(btnPage);
		
		btnPage->setScale(ButtonPageScale);
		btnPage->setPosition(Vec2(kButtonPadding + btnPage->getContentSize().width*ButtonPageScale / 2 + i * btnPage->getContentSize().width*ButtonPageScale + (i * space), btnBack->getPosition().y));
		this->addChild(btnPage);
	}
}

void LevelManager::tapBack()
{
    SoundManager::getInstance()->playSound(ESound::kSound_Click);
	SceneManager::getInstance()->changeScene(this, EScene::kScene_Menu);
}

void LevelManager::tapPage(cocos2d::Ref *pSender)
{
	if (LevelManager::s_isActive)
		return;

	Button* btnPage = (Button*)pSender;
	for (int i = 0; i < m_numPage; i++)
	{
		Button* btn = m_pages.at(i);
		if (btn->getTag() != btnPage->getTag())
		{
			btn->setEnabled(true);
			btn->loadTextureNormal("page-marker.png");
		}
		else
		{
			btn->setEnabled(false);

			btn->loadTextureNormal("page-marker_over.png");
			float distanceMove = -m_screenSize.width* (btn->getTag() - m_currPage);
			m_currPage = btn->getTag();
			m_panel->runAction(MoveBy::create(0.5f, Vec2(distanceMove, 0)));
		}
	}
    SoundManager::getInstance()->playSound(ESound::kSound_PageSwipe);
}



bool LevelManager::onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *event) {
    

    m_pTouchBegan = touch->getLocation();
    return true;
}


void LevelManager::onTouchEnded(cocos2d::Touch *touch, cocos2d::Event *event) {
    Point pEnd = touch->getLocation();
    if(pEnd.x == m_pTouchBegan.x || LevelManager::s_isActive)
        return;
    else
    {
        float distanceMove = 0;
        if(pEnd.x > m_pTouchBegan.x)
        {
            if(m_currPage > 1)
            {
            distanceMove = m_screenSize.width;
            Button* btnCurrent = m_pages.at(m_currPage - 1);
            btnCurrent->setEnabled(true);
            btnCurrent->loadTextureNormal("page-marker.png");
            
            Button* btnNew = m_pages.at(m_currPage - 2);
            btnNew->setEnabled(false);
                
            btnNew->loadTextureNormal("page-marker_over.png");
            m_currPage = btnNew->getTag();
            }
           
        }
        else
        {
            if(m_currPage < m_numPage)
            {
            distanceMove = -m_screenSize.width;
            Button* btnCurrent = m_pages.at(m_currPage-1);
            btnCurrent->setEnabled(true);
            btnCurrent->loadTextureNormal("page-marker.png");
            
            Button* btnNew = m_pages.at(m_currPage);
            btnNew->setEnabled(false);
            
            btnNew->loadTextureNormal("page-marker_over.png");
            m_currPage = btnNew->getTag();
            }

        }
        if(distanceMove != 0)
            SoundManager::getInstance()->playSound(ESound::kSound_PageSwipe);
        
        m_panel->runAction(MoveBy::create(0.5f, Vec2(distanceMove, 0)));

    }
}

void LevelManager::onKeyReleased(EventKeyboard::KeyCode keyCode, cocos2d::Event *event)
{
	if (keyCode == EventKeyboard::KeyCode::KEY_BACKSPACE)
	{
        SoundManager::getInstance()->playSound(ESound::kSound_Click);
		SceneManager::getInstance()->changeScene(this, EScene::kScene_Menu);
	}
}


